#ifdef UTIL_PLATFORM_WIN32
#include "io/File.h"
#include "lang/Exception.h"
#include <shlwapi.h>
#include <windows.h>
#include <cstddef>
#include <fileapi.h>
#pragma comment(lib, "shlwapi.lib")

using namespace yzrilyzr_lang;
namespace yzrilyzr_io{
	String File::getAbsolutePath() const{
		// 1. 检查路径是否为空
		if(path.empty()){
			return "";
		}

		char absolutePath[MAX_PATH]={0};

		// 2. 判断是否为相对路径 (不以 '/' 开头)
		if(!path.startsWith("/")&&!path.contains(":")){
			// --- 处理相对路径 ---

			// 获取当前工作目录
			char currentDir[MAX_PATH]={0};
			if(GetCurrentDirectoryA(MAX_PATH, currentDir) == 0){
				return ""; // 无法获取当前目录，返回空
			}

			// 拼接当前目录和相对路径
			String combinedPath=String(currentDir) + "\\" + path;

			// 将拼接后的路径转换为规范的绝对路径
			if(PathCanonicalizeA(absolutePath, combinedPath.c_str())){
				return absolutePath;
			}
		} else{
			// --- 处理绝对路径 (以 '/' 开头) ---

			// 直接对绝对路径进行规范化
			if(PathCanonicalizeA(absolutePath, path.c_str())){
				return absolutePath;
			}
		}

		// 3. 如果所有尝试都失败，返回空字符串
		return "";
	}
	std::vector<String> File::list()const{
		std::vector<String> fileList;
		// 用 "\\*" 匹配所有文件/目录（含无扩展名）
		std::string searchPath=getAbsolutePath().tostring() + "\\*";
		WIN32_FIND_DATAA findData;
		LPWIN32_FIND_DATAA pfindData=(LPWIN32_FIND_DATAA) & findData;
		HANDLE hFind=FindFirstFileA(searchPath.c_str(),pfindData);

		if(hFind != INVALID_HANDLE_VALUE){
			do{
				const String fileOrDir=findData.cFileName;
				if(fileOrDir != "." && fileOrDir != ".."){
					// 用 "\\" 拼接完整路径，与 Windows 习惯一致
					fileList.push_back(path + "\\" + fileOrDir);
				}
				// 检查是否是“无更多文件”（正常退出），还是其他错误
			} while(FindNextFileA(hFind, &findData) != 0 || GetLastError() != ERROR_NO_MORE_FILES);
			FindClose(hFind);
		} else{
			std::cerr << "Error accessing directory: " << path.c_str() << " (Error: " << GetLastError() << ")" << std::endl;
		}
		return fileList;
	}
	uint64_t File::length() const{
		HANDLE hFile=CreateFileA(
			path.c_str(),
			GENERIC_READ,
			FILE_SHARE_READ,
			NULL,
			OPEN_EXISTING,
			FILE_ATTRIBUTE_NORMAL,
			NULL
		);
		if(hFile == INVALID_HANDLE_VALUE){
			throw IOException("无法打开文件: " + path + "，错误码: " + std::to_string(GetLastError()));
		}
		LARGE_INTEGER fileSize;
		BOOL success=GetFileSizeEx(hFile, &fileSize);
		CloseHandle(hFile);
		if(!success){
			throw IOException("无法获取文件大小: " + path + "，错误码: " + std::to_string(GetLastError()));
		}
		// 修复：u_index 可能小于 int64_t（32位系统），需强制转换且避免溢出
		return static_cast<uint64_t>(fileSize.QuadPart);
	}
	bool File::exists() const{
		DWORD attr=GetFileAttributesA(path.c_str());
		return (attr != INVALID_FILE_ATTRIBUTES);
	}
	bool File::isFile() const{
		DWORD attr=GetFileAttributesA(path.c_str());
		return (attr != INVALID_FILE_ATTRIBUTES) &&
			!(attr & FILE_ATTRIBUTE_DIRECTORY);
	}
	bool File::isDirectory() const{
		DWORD attr=GetFileAttributesA(path.c_str());
		return (attr != INVALID_FILE_ATTRIBUTES) &&
			(attr & FILE_ATTRIBUTE_DIRECTORY);
	}
	bool File::deleteFile() const{
		if(!exists()) return false;
		if(isFile()) return DeleteFileA(path.c_str()) != 0;
		if(isDirectory()){
			bool isEmpty=PathIsDirectoryEmptyA(path.c_str()) != 0;
			return isEmpty?(RemoveDirectoryA(path.c_str()) != 0):false;
		}
		return false;
	}
	bool File::mkdirs() const{
		if(exists()){
			return isDirectory();
		}
		String dirPath=path.replace("/","\\");
		// 递归创建每一级目录（从根到子）
		u_index pos=0;
		do{
			pos=dirPath.indexOf('\\', pos + 1);
			String subDir=dirPath.substring(0, pos);
			if(subDir.empty()) continue; // 跳过空路径（如根目录）

			// 检查子目录是否存在
			DWORD attr=GetFileAttributesA(subDir.c_str());
			if(attr == INVALID_FILE_ATTRIBUTES){
				// 不存在则创建
				if(!CreateDirectoryExA(nullptr, subDir.c_str(), nullptr)){
					return false;
				}
			} else if(!(attr & FILE_ATTRIBUTE_DIRECTORY)){
				// 存在但不是目录，冲突
				return false;
			}
		} while(pos != std::string::npos);
		// 创建最后一级目录
		return CreateDirectoryExA(nullptr, dirPath.c_str(), nullptr) != 0;
	}
}
#endif // _WIN32